<template>
  <div ref="messageItem">
    <!-- 用户消息 -->
    <div v-if="message.role === 'USER'" class="">
      <div class="text-sm font-semibold justify-start items-center flex gap-1">
        <el-avatar :size="20" :src="userInfo.avatar" />
        {{ userInfo.uname }}
      </div>
      <div class="flex justify-end flex-col items-start gap-2 mt-1">
        <span class="px-3 py-[10px] text-sm break-all max-w-full">{{
          (message.messages[0].body as QueryMessage).query
        }}</span>
        <span
          v-if="queryMessage.ref"
          class="bg-background-04 black:bg-background-04-dark mx-2 px-2 py-1 rounded text-xs"
        >
          <span class="flex items-center justify-start gap-[6px]">
            <el-icon>
              <SelectSection v-if="queryMessage.ref.type === 'SECTION'" />
              <SelectContent v-else />
            </el-icon>
            {{ SELECTTYPE[queryMessage.ref.select_title!] }}
          </span>
          <p class="text-text-03 black:text-text-03-dark mt-1 line-clamp-2">
            “{{ queryMessage.ref.select_content }}”
          </p>
        </span>
      </div>
    </div>
    <!-- 机器人消息 -->
    <div
      v-else
      class="text-text-01 black:text-text-01-dark"
      @mouseover="showTool = true"
      @mouseout="showTool = false"
    >
      <div class="text-sm font-semibold justify-start items-center flex gap-1 mt-5">
        <el-avatar :size="20" src="./images/robot.png" />
        Aime
      </div>
      <!-- 加载状态 -->
      <div v-if="messageLoading" class="flex justify-start items-center mt-2">
        <span
          class="text-sm px-3 flex justify-center gap-1 items-center py-[10px] bg-background-01 black:bg-background-01-dark rounded-lg rounded-tl-sm"
        >
          <el-icon class="animate-spin">
            <MessageLoading />
          </el-icon>
          {{ currentStatus }}</span
        >
      </div>

      <!-- 消息卡片（聚合多条不同种类消息） -->
      <div class="px-3 rounded-tr-lg rounded-tl-sm" v-if="message.messages.length">
        <div class="pt-2" v-for="item in message.messages" :key="item.id">
          <!-- 文本类型 -->
          <div v-if="item.type === 'TEXT' || item.type === 'RAG_CONTENT'" class="text-sm break-all">
            <ChatText :text="(item.body as TextMessage).content" />
          </div>
          <!-- 模块类型 -->
          <div v-if="item.type === 'SECTION'">
            <chat-section :data="item.body as Section" :askId="item.ask_id"></chat-section>
          </div>
          <!-- 大纲类型 -->
          <div v-if="item.type === 'OUTLINE'"></div>
          <!-- 生成分析页面类型 -->
          <div v-if="item.type === 'PID'"></div>
          <!-- RAG溯源列表 -->
          <div v-if="item.type === 'RAG_SOURCE'">
            <div
              class="flex justify-start items-center gap-1 text-xs flex-wrap relative"
              :class="{ 'h-[24px] overflow-hidden': !showDetailRagSouce }"
            >
              <span class="text-text-02 black:text-text-02-dark">来源:</span>
              <span
                class="max-w-[120px] px-2 py-[2px] gap-1 rag-source-item border-base"
                v-for="(source, index) in item.body as RAGSource[]"
                :class="{ 'ml-[30px]': index % 2 === 0 && index !== 0 }"
                :key="source.index"
                @click="openUrl(source)"
                v-track:click="{
                  id: 'thspc_f10_copilot_chatpanel_URL',
                  logmap: () => ({ content: source.url })
                }"
              >
                <span>{{ source.index }}</span>
                <el-icon>
                  <NetWork v-if="source.jump_type === 'normal'" />
                  <NetSearch v-if="source.jump_type === 'data_query'" />
                </el-icon>
                <span class="truncate">{{ source.title }}</span>
              </span>
              <span
                v-if="(item.body as RAGSource[]).length > 2 && !showDetailRagSouce"
                @click="showDetailRagSouce = true"
                class="absolute right-[18px] top-0 w-[28px] font-semibold border-base rag-source-item"
                >+1</span
              >
              <span
                @click="showDetailRagSouce = false"
                v-if="(item.body as RAGSource[]).length > 2"
                class="w-[50px] border-base rag-source-item"
              >
                <el-icon>
                  <HideRagSource class="rotate-180" />
                </el-icon>
                &nbsp;收起
              </span>
            </div>
          </div>
        </div>
      </div>

      <!-- 异常状态 -->
      <div
        v-if="message.messages.length === 0 && !messageLoading"
        class="px-3 py-[10px] rounded-lg rounded-tl-sm text-sm mb-4 mt-1"
      >
        <span>会话异常，请点击重试或修改问句重新生成...</span>
        <span
          @click="regenerateMessage"
          class="flex justify-start items-center text-text-05 black:text-text-05-dark mt-2 gap-[6px] cursor-pointer"
          v-if="latest"
        >
          <el-icon><RegenerateChat /></el-icon>
          重试
        </span>
      </div>

      <!-- 工具栏<点赞、点踩、重新生成> -->
      <div class="h-6 rounded-b-lg px-[14px] gap-3 flex justify-end items-center">
        <el-icon
          v-show="message.messages.length && (latest || showTool)"
          @click="islike('like')"
          class="cursor-pointer text-text-03 black:text-text-02-dark hover:!text-text-04 black:hover:!text-text-04-dark"
          :class="{ '!text-text-04': message.like === 1 }"
          v-track:click="{ id: 'thspc_f10_copilot_chatpanel_likes', logmap: () => {} }"
          ><Like
        /></el-icon>
        <el-icon
          v-show="message.messages.length && (latest || showTool)"
          @click="islike('dislike')"
          class="cursor-pointer text-text-03 black:text-text-02-dark hover:!text-text-04 black:hover:!text-text-04-dark"
          :class="{ '!text-text-04': message.like === 0 }"
          ><Dislike
        /></el-icon>
        <el-icon
          v-if="message.messages.length && latest"
          @click="regenerateMessage"
          class="cursor-pointer !text-text-03 black:!text-text-02-dark hover:!text-text-04 black:hover:!text-text-04-dark"
          v-track:click="{ id: 'thspc_f10_copilot_chatpanel_regenation', logmap: () => {} }"
          ><RegenerateChat
        /></el-icon>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import type {
  ChatMessages,
  QueryMessage,
  TextMessage,
  RAGSource
} from '@/common/models/chat-message'
import ChatSection from './ChatSection.vue'
import ChatText from './ChatText.vue'
import type { Section } from '@/common/models/recommend-result'
import { nextTick, onMounted, ref, computed } from 'vue'
import {
  MessageLoading,
  Like,
  Dislike,
  RegenerateChat,
  SelectSection,
  NetWork,
  HideRagSource,
  NetSearch
} from '@/components/icons'
import { getEventBus } from '@/common/services/chat-event-bus'
import { ERRORTYPE, SELECTTYPE } from '@/common/config/const'
import { feedback } from '../../services/chat-api'
import { ElMessage } from 'element-plus'
import { APIURL } from '@/common/config/const'

const props = defineProps<{
  chatMessages: ChatMessages
  latest: boolean
}>()

const emits = defineEmits(['islike'])

const { messageUpdateEventBus, messageRegenerateEventBus } = getEventBus()

// 消息展示层
const message = ref(props.chatMessages)
// 消息Dom元素
const messageItem = ref()
// 消息正在传输
const messageLoading = ref(false)
// 当前状态
const currentStatus = ref('正在解析')

const queryMessage = message.value.messages[0]?.body as QueryMessage

const userInfo = computed(() => window.loginIssue.getUser())

const showTool = ref(false)

const showDetailRagSouce = ref(false)

onMounted(async () => {
  if (props.latest) {
    if (message.value.id === 'latest' && message.value.role === 'ASSISTANT') {
      messageLoading.value = true
    }
    await nextTick()
    updateView()
  }
})

// 监听：消息更新
messageUpdateEventBus.on(async ({ id, status }) => {
  if (id === message.value.id && message.value.role === 'ASSISTANT') {
    messageLoading.value = true
    currentStatus.value = status?.description || currentStatus.value
    if (status?.current === 'close') {
      messageLoading.value = false
      return
    }
    message.value.messages = Array.from(props.chatMessages.messages)
    await nextTick()
    updateView()
  }
})

// 交互：更新视图至可视区域内
function updateView() {
  messageItem.value?.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' })
}

// 交互：重新生成消息
function regenerateMessage() {
  messageRegenerateEventBus.emit({ id: message.value.id })
}

async function islike(key: string) {
  try {
    if (key === 'like') {
      await feedback({ ask_id: message.value.id, like: 1, feedback: null })
      message.value.like = 1
      ElMessage.success('点赞成功！')
      return
    } else {
      emits('islike', key)
    }
  } catch (error) {
    ElMessage.error('操作失败！')
    window.f10log(ERRORTYPE.AJAX, `点赞失败：${error}`, error)
  }
}

function openUrl(source: RAGSource) {
  if (source.jump_type === 'normal') {
    window.open(source.url)
    return
  }
  window.open(`${APIURL.iwencaiSearch}?w=${source.title}`)
}
</script>

<style lang="less">
.rag-source-item {
  @apply rounded-md after:rounded-md hover:after:border-border-04 black:hover:after:border-border-04-dark flex justify-center items-center cursor-pointer h-[24px];
  @apply text-text-03 black:text-text-03-dark hover:bg-background-13 black:hover:bg-background-13-dark hover:text-text-04 black:hover:text-text-04-dark;
}
</style>
